﻿using Dapper.DBContext;
using Guoc.BigMall.Domain.Entity;
using Guoc.BigMall.Infrastructure;
using Guoc.BigMall.Infrastructure.Extension;
using Guoc.BigMall.Infrastructure.Log;
using Guoc.BigMall.Infrastructure.Payment;
using Guoc.BigMall.WebService.Dto;
using System;
using System.Collections.Generic;
using System.Dynamic;
using System.Linq;
using Aop.Api;
using Aop.Api.Request;
using Aop.Api.Response;
using Guoc.BigMall.Infrastructure.Payment.Wechat;

namespace Guoc.BigMall.WebService.Implement
{
    public class MemberService : IMemberService
    {
        IUserContextService _userContext;
        IDBContext _db;
        IPayService _payService;
        ILogger _log;
        IAopClient _alipayClient;
        public MemberService(IDBContext dbContext, IUserContextService userContext, IPayService payService,ILogger log,IAopClient aopClient)
        {
            this._db = dbContext;
            _userContext = userContext;
            _payService = payService;
            _log = log;
            _alipayClient = aopClient;
        }

        /// <summary>
        ///  当前用户会分下信息
        /// </summary>
        /// <param name="page"></param>
        /// <param name="memberId">当前会员id</param>
        /// <returns></returns>
        public MyMemberVo QueryMyMembers(PageVo page,int memberId)
        {
            //  我的累计 7 代 子会员数
            MyMemberVo vo = new MyMemberVo();
            var curMember = _db.Table<DistributeMember>().FirstOrDefault(n => n.MemberId == memberId);
            if (curMember == null) {
                //当前用户不是分销会员
                return vo;   //  返回一个空统计
            }

            var grade = 7; // 默认7级分销

            // 我的直接子会员
            var sql = @"select m.Id, m.NickName,m.HeadImage,m.CreatedOn,m.Phone,m.SecondPhone from distribute_member dm inner join member m on dm.MemberId = m.Id
where 1=1 {0} Order By  m.Id desc LIMIT {1},{2}";
            var where = " and dm.ParentMemberId = @Pid";
            sql = string.Format(sql, where, (page.PageIndex - 1) * page.PageSize, page.PageSize);
            var rows = _db.DataBase.Query<MemberVo>(sql, new { Pid = memberId });
            // 
          
            vo.Items = rows;
            vo.MyMemberCount = _db.Table<DistributeMember>().Count(n => n.ParentMemberId == memberId);
   
           
            var sqlAll = "select count(*) from distribute_member dm where dm.path like @Path and Level between @Start and @End";
            // path like %#1#% 表示找出所有自己的子代， start = 1+ Level End = 7+Level ,表示 找出自己的第一代到第七代子孙
            vo.AllMemberCount = this._db.DataBase.ExecuteScalar<int>(sqlAll, 
                new { Path = string.Format("%#{0}#%", memberId), Start=1+curMember.Level ,End = curMember.Level+ grade });
            // 当天新增
            var sqltodayCount = @"select count(*) from distribute_member dm where dm.path like @Path 
and dm.Level between @Start and @End and  to_days(dm.CreatedOn) = to_days(now())";
            vo.TodayCount = this._db.DataBase.ExecuteScalar<int>(sqltodayCount,
               new { Path = string.Format("%#{0}#%", memberId), Start = 1 + curMember.Level, End = curMember.Level + grade });

            return vo;
        }

        public IEnumerable<SaleOrderVo> QueryMyOrders(PageVo page,MyOrderSearch search)
        {
            dynamic param = new ExpandoObject();
            var where = "";
            // 只查当前用户
            where += " and s.MemberId=@MemberId ";
            param.MemberId = search.MemberId;
            if (search.Status.HasValue && search.Status.Value != 0)
            {
                where += " and s.Status=@Status ";
                param.Status = search.Status;
            }
            string sql = @"Select s.Id,s.Code,s.Status,s.CreatedOn,i.Id as SaleOrderItemId,i.ProductId,i.ProductName,
i.ProductCode,i.SalePrice,i.RealPrice,i.Quantity,p.ImageUrl from SaleOrder s 
inner join SaleOrderItem i on s.Id = i.SaleOrderId 
inner join ProductPicture p on p.Id=i.ProductId
where 1=1 {0} Order By  s.Id desc LIMIT {1},{2}";
            sql = string.Format(sql, where, (page.PageIndex - 1) * page.PageSize, page.PageSize);
            var rows = (IEnumerable<SaleOrderListVo>)_db.DataBase.Query<SaleOrderListVo>(sql, param);

            //  按前端格式组装
            List<SaleOrderVo> orders = new List<SaleOrderVo>();
            foreach (var row in rows)
            {
                SaleOrderVo order = new SaleOrderVo()
                {
                    Id = row.Id,
                    Code = row.Code,
                    CreatedOn = row.CreatedOn,
                    Status = row.Status
                };
                order.Items = rows.Where(n => n.Id == row.Id).Select(item => new SaleOrderItemVo()
                {
                    Id = item.SaleOrderItemId,
                    ProductId = item.ProductId,
                    ProductCode = item.ProductCode,
                    ProductName = item.ProductName,
                    Quantity = item.Quantity,
                    RealPrice = item.RealPrice,
                    SalePrice = item.SalePrice,
                    ImageUrl = item.ImageUrl,

                }).ToList();

                orders.Add(order);
            }

            return orders;
        }

        public DistributeInfoVo QueryMyDistribute(PageVo page,int? cashStatus, int memberId)
        {
            dynamic param = new ExpandoObject();
            var where = "";
                // 会员存在，按照会员查询
                where += " and i.Memberid = @MemberId";
                param.MemberId = memberId;
            
            if (cashStatus.HasValue && cashStatus.Value != 0)
            {
                if (cashStatus.Value == 1)
                {
                    // 未提现
                    where += " and i.CashStatus=@CashStatus ";
                    param.CashStatus = cashStatus;
                }
                else
                {
                    // 已提现
                    where += " and i.CashStatus in (2,3) ";
                    param.CashStatus = cashStatus;
                }               
            }

            where += " and d.Status in (4,5)";  //  可提现状态 4，5

            string sql = @"select i.Id, d.`Status`,i.ProfitLevel,i.ProfitAmount,i.CashStatus,i.CreatedOn 
from distributeorder d inner join  distributeorderitem i on d.id = i.distributeorderid
where 1=1 {0} Order By  i.Id desc LIMIT {1},{2}";
            sql = string.Format(sql, where, (page.PageIndex - 1) * page.PageSize, page.PageSize);
            var rows = _db.DataBase.Query<DistributeOrderItemVo>(sql, param);

            string sqlAmount = @"select sum(i.ProfitAmount) from distributeorder d inner join  distributeorderitem i on d.id = i.distributeorderid
where 1=1 {0} group by i.MemberId";
            sqlAmount = string.Format(sqlAmount, where);
            var sumAmount = _db.DataBase.ExecuteScalar<decimal>(sqlAmount, param);

            DistributeInfoVo result = new DistributeInfoVo();
            result.Items = rows;

            var member= _db.Table<Member>().FirstOrDefault(mbr => mbr.Id == memberId);
            if (member == null) {
                throw new FriendlyException("会员不存在");
            }

            result.NoAlipayId = string.IsNullOrEmpty(member.AlipayId);
            result.SumAmount = sumAmount;
            return result;
        }

        public void SetAliPayId(int memberId, string AliPayId)
        {
            var entity = _db.Table<Member>().FirstOrDefault(n => n.Id == memberId);
            if (entity == null) {
                throw new FriendlyException("会员信息不存在");
            }
            entity.AlipayId = AliPayId;
            _db.Update(entity);
            _db.SaveChange();
        }

        public void CashToAlipay(AlipayCashDto model)
        {
          
            _log.Info("==申请支付宝提现===");
            // 开始提现
            var distributeOrderItem = _db.Table<DistributeOrderItem>().FirstOrDefault(item => item.Id == model.DistributeOrderItemId);
            if (distributeOrderItem == null)
            {
                throw new FriendlyException("提现记录不存在");
            }
            var distributeOrder = _db.Table<DistributeOrder>().FirstOrDefault(dorder => dorder.Id == distributeOrderItem.DistributeOrderId);
            if (distributeOrder == null)
            {
                throw new FriendlyException("提现订单不存在");
            }           

            var member = _db.Table<Member>().FirstOrDefault(mbr => mbr.Id == distributeOrderItem.MemberId);
            if (member == null)
            {
                throw new FriendlyException("会员不存在");
            }
            //没有支付宝账号，需要提供支付宝账号
            if (string.IsNullOrEmpty(member.AlipayId))
            {
                if (string.IsNullOrEmpty(model.AlipayId)) {
                    throw new FriendlyException("请设置支付宝账号");
                }

                member.AlipayId = model.AlipayId;
                _db.Update(member);
               
            }
            // 可提现
            distributeOrder.Finished();
            distributeOrderItem.Cashed();
                 

            AlipayFundTransToaccountTransferRequest request = new AlipayFundTransToaccountTransferRequest();
           Aop.Api.Domain.AlipayFundTransToaccountTransferModel reqData = new Aop.Api.Domain.AlipayFundTransToaccountTransferModel
            {
                OutBizNo = distributeOrder.Code,  //out_biz_no
                Amount = distributeOrderItem.ProfitAmount.ToString("0.00"),  //trans_amount
                PayeeAccount = member.AlipayId,   //identity
                PayeeType = member.AlipayId.StartsWith("2088") ? "ALIPAY_USER_ID" : "ALIPAY_LOGON_ID",   //identity_type
                PayeeRealName = member.AlipayId.StartsWith("2088") ? "" : member.RealName,  //name
                Remark = "开卡绩效津贴",  //remark
            };
            request.SetBizModel(reqData);

            // 3. 发起请求并处理响应
            AlipayFundTransToaccountTransferResponse response = _alipayClient.CertificateExecute(request);

            if (response.IsError)
            {
                throw new FriendlyException(string.Format("转账失败:{0}", response.SubMsg));
            }

            // 转账成功
            //记录提现记录
            TransactionHistory histroy = new TransactionHistory()
            {
                TradeType = TradeType.CashToAlipay,
                TradeKey = TradeKeyName.Alipay_Uni_Transfer,
                TradeName = "支付宝单笔转账",
                TradeCode = distributeOrder.Code,
                TradeAmount = distributeOrderItem.ProfitAmount,
                TradeContent = response.Body,
                OutTradeNo = response.OrderId,
                TradeDate = DateTime.Parse(response.PayDate)
            };
            _db.Insert(histroy);

          
            _db.Update(distributeOrder);
            _db.Update(distributeOrderItem);
            _db.SaveChange();



            _log.Info("==结束支付宝提现===");
        }

        public void CashToWechat(WechatCashDto model)
        {
            _log.Info("==申请微信提现===");
            var distributeOrderItem = _db.Table<DistributeOrderItem>().FirstOrDefault(item => item.Id == model.DistributeOrderItemId);
            if (distributeOrderItem == null)
            {
                throw new FriendlyException("提现记录不存在");
            }
            var distributeOrder = _db.Table<DistributeOrder>().FirstOrDefault(dorder => dorder.Id == distributeOrderItem.DistributeOrderId);
            if (distributeOrder == null) {
                throw new FriendlyException("提现订单不存在");
            }
           
            var member = _db.Table<Member>().FirstOrDefault(mbr => mbr.Id == distributeOrderItem.MemberId);
            if (member == null)
            {
                throw new FriendlyException("会员不存在");
            }
            // 开始提现
            distributeOrder.Finished();
            distributeOrderItem.Cashed();

            var openId = string.IsNullOrEmpty(model.OpenId) ? _userContext.Current.OpenId : model.OpenId;
           
            var wxPay = _payService.GetPayGetway<WechatGetway>(distributeOrder.StoreCode);
            PayRequest payreq = new PayRequest();
            payreq.Add("openid", openId);
            payreq.Add("partner_trade_no", distributeOrder.Code);
            payreq.Add("amount", Decimal.ToInt32(distributeOrderItem.ProfitAmount * 100));  // int.Parse(entity.OrderAmount*100));
            payreq.Add("check_name", "NO_CHECK");
            payreq.Add("desc", "开卡绩效津贴");
            payreq.Add("spbill_create_ip", model.IpAddress); //终端ip
            var response = wxPay.Transfers(payreq);

            // 转账成功
            //记录提现记录
            TransactionHistory histroy = new TransactionHistory()
            {
                TradeType = TradeType.CashToWechat,
                TradeKey = TradeKeyName.Wechat_transfers,
                TradeName = "微信单笔转账",
                TradeCode = distributeOrder.Code,
                TradeAmount = distributeOrderItem.ProfitAmount,
                TradeContent = payreq.ToXml(),
                OutTradeNo = response.GetValue<string>("payment_no"),
                TradeDate = DateTime.Parse(response.GetValue<string>("payment_time"))
            };
            _db.Insert(histroy);
           

            _db.Update(distributeOrder);
            _db.Update(distributeOrderItem);

            _db.SaveChange();



            _log.Info("==结束微信提现===");
        }
    }
}
